package com.xbongbong.sys.model.impl;

import com.alibaba.dingtalk.openapi.exception.OApiException;
import com.alibaba.dingtalk.openapi.helper.AuthHelper;
import com.alibaba.dingtalk.openapi.helper.Env;
import com.alibaba.dingtalk.openapi.helper.ServiceHelper;
import com.alibaba.dingtalk.openapi.helper.UserHelper;
import com.alibaba.fastjson.JSONObject;
import com.xbongbong.paas.redis.PaasRedisHelper;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.DateUtil;
import com.xbongbong.paas.toolbox.util.StringUtil;
import com.xbongbong.paas.toolbox.util.XssShieldUtil;
import com.xbongbong.sys.domain.dao.CompanyDao;
import com.xbongbong.sys.domain.entity.CompanyEntity;
import com.xbongbong.sys.domain.entity.FeeCompanyEntity;
import com.xbongbong.sys.model.CompanyModel;
import com.xbongbong.sys.model.FeeCompanyModel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * Description:
 *
 * @author 李杰
 * @version v1.0
 * @date 2019/2/19 10:06
 * @since v1.0
 */
@Service("companyModel")
public class CompanyModelImpl implements CompanyModel {

    private static final Logger LOG = LoggerFactory.getLogger(CompanyModelImpl.class);

    @Resource
    private CompanyDao companyDao;
    @Resource
    private FeeCompanyModel feeCompanyModel;
    @Resource
    private PaasRedisHelper paasRedisHelper;
    @Resource
    private AuthHelper authHelper;

    /**
     * 插入
     *
     * @param entity 实体
     * @return 是否成功
     */
    @Override
    public Integer insert(CompanyEntity entity) throws XbbException {
        insertFeeCompany(entity);
        entity.setCorpName(XssShieldUtil.stripXss(entity.getCorpName()));
        return companyDao.insert(entity);
    }

    /**
     * 更新公司信息
     * @param entity 公司实体
     * @return 受影响记录数
     * @throws XbbException 业务异常
     */
    @Override
    public Integer update(CompanyEntity entity) {
        entity.setCorpName(XssShieldUtil.stripXss(entity.getCorpName()));
        return companyDao.update(entity);
    }

    /**
     * 获取符合查询条件的记录
     *
     * @param param 查询条件
     * @return 符合查询条件的记录
     */
    @Override
    public List<CompanyEntity> findEntitys(Map<String, Object> param) {
        return companyDao.findEntitys(param);
    }

    /**
     * 获取符合查询条件的记录总数
     *
     * @param param 查询条件
     * @return 符合查询条件的记录总数
     */
    @Override
    public Integer getEntitysCount(Map<String, Object> param) {
        return companyDao.getEntitysCount(param);
    }

    @Override
    public List findEntitysWithoutSub(Map<String, Object> param) {
        return null;
    }

    @Override
    public Integer deleteByKey(String key){
        return companyDao.deleteByKey(key);
    }

    @Override
    public CompanyEntity getByKey(String key){
        return companyDao.getByKey(key);
    }

    @Override
    public Integer getEndTime(Map<String ,Object>  param){
        return companyDao.getEndTime(param);
    }

    @Override
    public List<Map<String,Object>> companyStatic(Map<String ,Object>  param){
        return companyDao.companyStatic(param);
    }

    @Override
    public List<Map<String,Object>> companyTotalNumDay(Map<String ,Object>  param){
        return companyDao.companyTotalNumDay(param);
    }

    @Override
    public List<Map<String,Object>> companyTotalNumHour(Map<String ,Object>  param){
        return companyDao.companyTotalNumHour(param);
    }

    @Override
    public List<Map<String,Object>> findFeeCompanyEntitys(Map<String ,Object>  param){
        return companyDao.findFeeCompanyEntitys(param);
    }

    @Override
    public List<String> getCorpIdByCorpNameLike(String corpNameLike) {
        return companyDao.getCorpIdListByCorpNameLike(corpNameLike);
    }


    @Override
    public List<CompanyEntity> getCompanyList(List<String> corpidIn) {
        if (corpidIn == null || corpidIn.size() < 1) {
            return new ArrayList<>();
        }
        Map<String, Object> companyParam = new HashMap<>(16);
        companyParam.put("corpidIn", corpidIn);
        return findEntitys(companyParam);
    }

    @Override
    public CompanyEntity getNormalCompanyByKey(String corpid){
        Map<String,Object> param = new HashMap<String,Object>();
        param.put("corpid", corpid);
        param.put("status", 1);
        param.put("del", 0);
        List<CompanyEntity> companyList = findEntitys(param);
        return companyList.size() > 0 ? companyList.get(0) : null;
    }

    @Override
    public CompanyEntity getByKeyIgnoreDel (String corpid) {
        Map<String, Object> param = new HashMap<>();
        param.put("corpid", corpid);

        List<CompanyEntity> list =  findEntitys(param);
        return list.size() > 0 ? list.get(0) : null;
    }


    /**
     * 更新单个公司的company表数据
     *
     * @param updateCorpid 公司id
     * @param suiteTokenPerm
     * @author kaka
     * @date 2016年7月27日 下午3:01:56
     */
    @Override
    public CompanyEntity updateCompanyInfo(String updateCorpid, String suiteTokenPerm) {
        String permanent_code = paasRedisHelper.getValue("permanentcode", updateCorpid);

        /*
         * 拿到permanent_code（永久授权码）后，向钉钉服务器获取企业的基本信息并插入库或更新数据库记录
         */
        JSONObject authInfo = ServiceHelper.getAuthInfo(suiteTokenPerm,
                Env.SUITE_KEY, updateCorpid, permanent_code);

        String authAgentId;
        try {
            authAgentId = authHelper.getAgentId(updateCorpid, Env.DING_XBB_APP_ID);
        } catch (OApiException e1) {
            LOG.error("获取agentId失败", e1);
            return null;
        }

        CompanyEntity company = getByKeyIgnoreDel(updateCorpid);
        boolean insertCompany = false;
        if (company == null) {
            company = new CompanyEntity();
            insertCompany = true;
            // 前面一步对企业进行了激活，所以这里讲入库的企业设为正常状态，同步不要修改status
            company.setStatus(1);
            // 将公司del置为0，同步不要修改status
            company.setDel(0);
        }
        JSONObject userIInfo = null;
        try {
            String accessToken = authHelper.getAccessToken(updateCorpid);
            userIInfo = UserHelper.getCompanyUsers(accessToken);
        } catch (OApiException e) {
            LOG.error("updateCompanyInfo error: corpid = " + updateCorpid, e);
        }
        if (Objects.nonNull(userIInfo)) {
            Integer count = userIInfo.getInteger("count");
            if (Objects.nonNull(count)) {
                company.setUserNum(count);
            }
        }
        company.formatCompanyData(authInfo);
        company.setPermanentCode(permanent_code);

        // 设置agentId
        company.setAgentId(authAgentId);
        try {
            if (insertCompany) {
                insert(company);
            } else {
                update(company);
            }
            return company;
        } catch (Exception e) {
            LOG.error("获取agentId失败", e);
            return null;
        }
    }

    /**
     * 如果系统里没有套餐信息则插入一个免费套餐，如果存在（即是钉钉付费应用过来的套餐）且公司名称不存在则更新公司名称
     * @param entity CompanyEntity
     * @author chenhb
     */
    private void insertFeeCompany(CompanyEntity entity) throws XbbException {
        Map<String,Object> param = new HashMap<>(16);
        param.put("corpid", entity.getCorpid());
        param.put("del", 0);
        param.put("start", 0);
        param.put("pageNum", 1);
        List<FeeCompanyEntity> feeCompanyList = feeCompanyModel.findEntitys(param);

        if (feeCompanyList.isEmpty()) {
            entity.setCorpName(XssShieldUtil.stripXss(entity.getCorpName()));
            //insert的时候渠道码就是取的公司的
            companyDao.insertFeeCompany(entity);
        } else {
            FeeCompanyEntity feeCompanyEntity = feeCompanyList.get(0);
            if(StringUtil.isEmpty(feeCompanyEntity.getCorpName())){
                feeCompanyEntity.setCorpName(XssShieldUtil.stripXss(entity.getCorpName()));

                //当渠道码为空的时候，同步公司渠道码
                if(StringUtil.isEmpty(feeCompanyEntity.getAuthChannel())){
                    feeCompanyEntity.setAuthChannel(entity.getAuthChannel());
                }

                feeCompanyEntity.setUpdateTime(DateUtil.getInt());
                feeCompanyModel.update(feeCompanyEntity);
            }
        }
    }

    @Override
    public List<String> getJxcCorpidList() {
        return companyDao.getJxcCorpidList();
    }

    @Override
    public List<String> getJxcCorpidListByActive() {
        return companyDao.getJxcCorpidListByActive();
    }

    @Override
    public List<String> getCorpidList() {
        return companyDao.getCorpidList();
    }

    @Override
    public List<String> getCorpidListByStatus() {
        return companyDao.getCorpidListByStatus();
    }
    /**
     * 获取没有配置钉钉待办的公司corpid
     * @author xingxing.xiao
     * @date 2019/09/26 10:04
     */
    @Override
    public List<String> getCorpidListNotInCompanyConfig(String configAlias) {
        return companyDao.getCorpidListNotInCompanyConfig(configAlias);
    }

    @Override
    public Map<String, String> getCorpIdNameMap(Collection<String> corpidIn) {
        if (corpidIn == null || corpidIn.size() < 1) {
            return new HashMap<>(1);
        }
        Map<String, Object> companyParam = new HashMap<>(1);
        companyParam.put("corpidIn", corpidIn);
        List<CompanyEntity> companyList = findEntitys(companyParam);
        Map<String, String> corpIdNameMap = new HashMap<>(companyList.size());
        for (CompanyEntity company : companyList) {
            String corpid = company.getCorpid();
            String corpName = company.getCorpName();
            corpIdNameMap.put(corpid, corpName);
        }
        return corpIdNameMap;
    }

    @Override
    public List<String> getJxcCorpidListTemporary() {
        return companyDao.getJxcCorpidListTemporary();
    }

    @Override
    public void insertBatch(List<String> subList) {
        companyDao.insertBatch(subList);
    }

    @Override
    public List<String> getCorpidListByActive() {
        return companyDao.getCorpidListByActive();
    }
}

